﻿using System;
using System.AutoUpdate.Core;
using System.AutoUpdate.Core.Operations;
using System.AutoUpdate.Interfaces;
using System.AutoUpdate.Library;
using System.AutoUpdate.Managers;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace System.AutoUpdate.Operations
{
    /// <summary>
    /// Verifies update info with online checks
    /// </summary>
    public class VerifyOperation : BackgroundOperation
    {
        public override bool StartOperation (UpdateInfo info)
        {
            if (info == null)
            {
                return false;
            }

            Info = info;

            if (SourceManager.Instance.Sources.Count > 0)
            {
                OperationEvent (Core.OperationEvent.Started, this, new OperationEventArgs ());

                Run ();

                return true;
            }

            return false;
        }

        protected override void WorkerOnDoWork (object sender, DoWorkEventArgs doWorkEventArgs)
        {
            //
            // Verify all updates, if a single signature fails, it is removed.
            //

            HashSet<UpdateVersionInfo> verifiedVersions = new HashSet<UpdateVersionInfo>();

            int count = 0;

            foreach (UpdateVersionInfo version in Info.AvailableVersions)
            {
                Worker.ReportProgress((int)(count / (double)Info.AvailableVersions.Count * 100.0));

                count++;

                if (!version.File.IsTransfered)
                {
                    continue;
                }

                foreach (IUpdateSource source in SourceManager.Instance.Sources)
                {
                    if (!source.HasVersion (version))
                    {
                        continue;
                    }

                    if (source.CheckSignature (version))
                    {
                        verifiedVersions.Add (version);
                    }
                }
            }

            Info.AvailableVersions.Clear ();
            
            foreach (UpdateVersionInfo version in verifiedVersions)
            {
                Info.AvailableVersions.Add(version);
            }
        }
    }
}
